package com.zhoutao.blog.seven.dao.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.zhoutao.blog.seven.dao.mapper.TagMapper;
import com.zhoutao.blog.seven.dao.mapper.TagRelationMapper;
import com.zhoutao.blog.seven.dao.model.TagDao;
import com.zhoutao.blog.seven.dao.model.TagRelationDao;
import com.zhoutao.blog.seven.dao.model.TupleDao;
import com.zhoutao.blog.seven.model.enums.RefType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TagRelationRepository extends ServiceImpl<TagRelationMapper, TagRelationDao> {

    @Autowired
    private TagMapper tagMapper;

    /**
     * 更新标签关系
     *
     * @param refId   关联的资源ID
     * @param refType 资源类型ID
     * @param tags    标签ID
     */
    @Transactional
    public void updateTagRelation(Long refId, RefType refType, List<String> tagNames) {
        if (CollectionUtils.isEmpty(tagNames)) {
            this.clean(refId, refType);
            return;
        }
        // 查询标签
        List<TagDao> existTags = tagMapper.findByNames(tagNames);
        Set<String> existTagNames = existTags.stream().map(TagDao::getName).collect(Collectors.toSet());

        // 过滤出缺少的并保存
        for (String tagName : tagNames) {
            if (!existTagNames.contains(tagName)) {
                TagDao tagDao = new TagDao().setName(tagName);
                tagMapper.insert(tagDao);
                existTags.add(tagDao);
            }
        }

        // 清除关联记录
        this.clean(refId, refType);


        // 新增关联记录
        List<TagRelationDao> tagRelations = existTags.stream().map(tag ->
                new TagRelationDao()
                        .setTagId(tag.getId())
                        .setRefId(refId)
                        .setRefType(refType.name())).collect(Collectors.toList());
        this.saveBatch(tagRelations);
    }

    public void clean(Long refId, RefType refType) {
        LambdaQueryWrapper<TagRelationDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TagRelationDao::getRefId, refId)
                .eq(TagRelationDao::getRefType, refType.name());
        this.remove(wrapper);
    }

    /**
     * 查询标签关联的资源类型
     *
     * @param tagIds 标签集合
     * @return
     */
    public Map<Long, Long> groupByTagId(List<Long> tagIds) {
        if (CollectionUtils.isEmpty(tagIds)) {
            return Collections.emptyMap();
        }
        List<TupleDao<Long, Long>> countList = this.baseMapper.count(tagIds);
        if (CollectionUtils.isEmpty(countList)) {
            return Collections.emptyMap();
        }

        Map<Long, Long> countMap = Maps.newHashMap();
        for (TupleDao<Long, Long> tuple : countList) {
            countMap.put(tuple.getKey(), tuple.getValue());
        }

        return countMap;
    }

    public void cleanAll() {
        this.baseMapper.delete(new LambdaQueryWrapper<>());
    }
}
